namespace Guia.Elements
{
    using System;
    using System.Windows.Automation;
    using Guia.Core;
    using Guia.Elements.PatternServants;
    using Guia.Locator;

    /// <summary>
    /// This class represents a DatePicker
    /// </summary>
    public class DatePicker : UiElement, IExpandCollapse
    {
        /// <summary>
        /// Represents a helper-servant for the ExpandCollapse-pattern.
        /// </summary>
        private readonly IExpandCollapse expandCollapseServant;

        /// <summary>
        /// The underlying TextBox which contains the text value.
        /// </summary>
        private readonly TextBox valueTextBox;

        /// <summary>
        /// Initializes a new instance of the <see cref="DatePicker"/> class.
        /// </summary>
        /// <param name="automationElement">
        /// The automation element.
        /// </param>
        public DatePicker(AutomationElement automationElement) : base(automationElement)
        {
            this.expandCollapseServant = new ExpandCollapseImpl(this);
            this.valueTextBox = this.Get<TextBox>("PART_TextBox");
        }

        /// <summary>
        /// Gets the default-condition to find a control by its type.
        /// </summary>
        public static SearchCondition ControlTypeCondition
        {
            get { return SearchCondition.ByControlType(ControlType.Custom).And(SearchCondition.ByClassName("DatePicker")); }
        }

        /// <summary>
        /// Gets or sets the date.
        /// </summary>
        /// <exception cref="OperationNotSupportedException">
        /// </exception>
        public DateTime Date
        {
            get
            {
                try
                {
                    string tmpValue = this.ValuePattern.Current.Value;
                    DateTime value = DateTime.Parse(tmpValue);
                    return value;
                }
                catch (FormatException ex)
                {
                    throw new OperationNotSupportedException("Could not get the date. " + ex.Message);
                }
            }
            
            set
            {
                try
                {
                    this.ValuePattern.SetValue(value.ToLongDateString());
                }
                catch (ElementNotEnabledException ex)
                {
                    throw new OperationNotSupportedException(ex.Message);
                }
            }
        }

        /// <summary>
        /// Gets the text value of this DatePicker.
        /// </summary>
        public string TextValue
        {
            get
            {
                return this.valueTextBox.Value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this DatePicker is expanded or not.
        /// </summary>
        public bool IsExpanded
        {
            get
            {
                return this.expandCollapseServant.IsExpanded;
            }

            set
            {
                this.expandCollapseServant.IsExpanded = value;
            }
        }

        /// <summary>
        /// Gets the ValuePattern.
        /// </summary>
        private ValuePattern ValuePattern
        {
            get
            {
                return this.GetPattern<ValuePattern>();
            }
        }

        /// <summary>
        /// Tries to get the Date.
        /// </summary>
        /// <param name="dateTime">
        /// The date variable. The current DateTime is assigned to this variable.
        /// </param>
        /// <returns>
        /// True by success, false otherwise. 
        /// </returns>
        public bool TryGetDate(out DateTime dateTime)
        {
            bool result;
            try
            {
                string tmpValue = this.ValuePattern.Current.Value;
                dateTime = DateTime.Parse(tmpValue);
                result = true;
            }
            catch (Exception)
            {
                result = false;
                dateTime = new DateTime();
            }

            return result;
        }

        /// <summary>
        /// Expands the DatePicker.
        /// </summary>
        /// <exception cref="OperationNotSupportedException">This exception is thrown when the element is disabled.</exception>
        public void Expand()
        {
            this.expandCollapseServant.Expand();
        }

        /// <summary>
        /// Collapses the DatePicker.
        /// </summary>
        /// <exception cref="OperationNotSupportedException">This exception is thrown when the element is disabled.</exception>
        public void Collapse()
        {
            this.expandCollapseServant.Collapse();
        }
    }
}